import G6 from '@antv/g6'
import type { IGroup, ModelConfig } from '@antv/g6'
import { DEFAULT_NODE_SIZE } from '@/config'
import { getIconUrl } from '@/components/topoIcons'

export const DEVICE_NODE = 'device_node'

const statusColorMap = {
  normal: '#5B8FF9',
  warning: '#FF4D4F',
}
const SHAPE_BOUNDING_NAME = 'bounding-rect'
const PADDING = 6

// 存储动画实例的WeakMap，防止内存泄漏
const animationMap = new WeakMap<IGroup, { stop: () => void }>()

export const registerDeviceNode = () => {
  G6.registerNode(DEVICE_NODE, {
    draw(cfg?: ModelConfig, group?: IGroup) {
      if (!group || !cfg) return {}
      //console.log('deviceNode-', cfg)
      const { icon } = cfg

      const size = DEFAULT_NODE_SIZE // cfg.size
      const color = cfg.status ? '#FF4D4F' : cfg.color || '#5B8FF9'
      const label = cfg.label
      const ip = cfg.id || cfg.ip || ''

      let maxWidth = size
      let totalHeight = size

      // 绘制主形状（矩形或图标）
      let mainShape
      if (icon) {
        mainShape = group.addShape('image', {
          attrs: {
            x: -size / 2,
            y: -size / 2,
            width: size,
            height: size,
            img: getIconUrl(icon),
          },
          name: 'icon-shape',
          draggable: true,
        })
      } else {
        mainShape = group.addShape('rect', {
          attrs: {
            x: -size / 2,
            y: -size / 2,
            width: size,
            height: size,
            fill: color,
            radius: 4,
          },
          name: 'rect-shape',
          draggable: true,
        })
      }

      const offset = 15

      // 添加label文本（显示在形状下方）
      if (label) {
        const labelShape = group.addShape('text', {
          attrs: {
            text: label,
            x: 0,
            y: size / 2 + offset,
            textAlign: 'center',
            fill: '#333',
            fontSize: 12,
          },
          name: 'label-text-shape',
        })
        const labelWidth = labelShape.getBBox().width
        const labelHeight = labelShape.getBBox().height
        maxWidth = Math.max(maxWidth, labelWidth)
        totalHeight += labelHeight
      }

      // 添加ip文本（显示在label下方）
      if (ip) {
        const ipShape = group.addShape('text', {
          attrs: {
            text: ip,
            x: 0,
            y: size / 2 + offset + 10,
            textAlign: 'center',
            fill: '#666',
            fontSize: 10,
          },
          name: 'ip-text-shape',
        })
        const ipWidth = ipShape.getBBox().width
        const ipHeight = ipShape.getBBox().height
        maxWidth = Math.max(maxWidth, ipWidth)
        totalHeight += ipHeight
      }

      // 创建包裹所有图形的矩形边框（初始透明）
      group.addShape('rect', {
        attrs: {
          x: -maxWidth / 2 - PADDING,
          y: -size / 2 - PADDING,
          width: maxWidth + PADDING * 2,
          height: totalHeight + PADDING * 2,
          fill: 'transparent',
          stroke: 'transparent',
          radius: 4,
          lineWidth: 2,
        },
        name: SHAPE_BOUNDING_NAME,
        draggable: true,
        zIndex: -1, // 确保在最底层
      })

      return mainShape
    },
    setState(name, value, item) {
      if (name === 'status') {
        // 更新边框颜色
        const group = item?.getContainer()
        const boundingRect = group?.find(
          ele => ele.cfg.name === SHAPE_BOUNDING_NAME
        )

        if (boundingRect && group) {
          // 清除之前的动画
          const oldAnimation = animationMap.get(group)
          oldAnimation?.stop()

          if (value === 'warning') {
            // 创建呼吸动画
            boundingRect.animate(
              (ratio: number) => {
                // 使用正弦函数创建平滑的透明度变化
                const opacity = Math.sin(ratio * Math.PI * 2) * 0.5 + 0.5
                return {
                  stroke: statusColorMap.warning,
                  strokeOpacity: opacity,
                }
              },
              {
                duration: 5000,
                repeat: true,
              }
            )

            // 存储动画引用以便后续清理
            animationMap.set(group, {
              stop: () => {
                animationMap.delete(group)
              },
            })
          } else {
            // 非警告状态，恢复普通样式
            boundingRect.stopAnimate()
            boundingRect.attr({
              stroke: statusColorMap[value] ?? statusColorMap.normal,
              strokeOpacity: 0,
            })
          }
        }
      }
    },
    // 添加销毁时的清理逻辑
    destroy(cfg, group) {
      if (group) {
        const animation = animationMap.get(group)
        animation?.stop()
      }
    },
  })
}
